Cluster தொகுதி என்றால் என்ன?
Cluster தொகுதி ஒரே சேவையக போர்ட்டைப் பகிர்ந்து கொள்ளும் பல தொழிலாளர் செயல்முறைகளை உருவாக்க ஒரு வழியை வழங்குகிறது.
Node.js இயல்பாக single-threaded ஆக இருப்பதால், Cluster தொகுதி பல-கோர் அமைப்புகளில் செயல்திறனைக் கணிசமாக மேம்படுத்த உங்கள் பயன்பாட்டை பல CPU கோர்களைப் பயன்படுத்த உதவுகிறது.
ஒவ்வொரு தொழிலாளரும் தங்கள் சொந்த செயல்முறையில் தங்கள் சொந்த இவெண்ட் லூப் மற்றும் நினைவக இடத்தில் இயங்குகிறார்கள், ஆனால் அவர்கள் அனைவரும் ஒரே சேவையக போர்ட்டைப் பகிர்ந்து கொள்கிறார்கள்.
மாஸ்டர் செயல்முறை தொழிலாளர்களை உருவாக்குவதற்கும் உள்வரும் இணைப்புகளை அவர்களுக்கிடையே விநியோகிப்பதற்கும் பொறுப்பாகும்.
Cluster தொகுதியை இறக்குமதி செய்தல்
Cluster தொகுதி Node.js இல் இயல்பாகச் சேர்க்கப்பட்டுள்ளது.
உங்கள் ஸ்கிரிப்ட்டில் அதைத் தேவைப்படுவதன் மூலம் பயன்படுத்தலாம்:
const cluster = require('cluster');
const os = require('os');
// Check if this is the master process
if (cluster.isMaster) {
console.log(`Master process ${process.pid} is running`);
} else {
console.log(`Worker process ${process.pid} started`);
}
Clustering எவ்வாறு செயல்படுகிறது
Cluster தொகுதி பல தொழிலாளர் செயல்முறைகளைத் தோற்றுவிக்கும் ஒரு மாஸ்டர் செயல்முறையை உருவாக்குவதன் மூலம் செயல்படுகிறது.
மாஸ்டர் செயல்முறை பயன்பாட்டு குறியீட்டை இயக்காது, ஆனால் தொழிலாளர்களை நிர்வகிக்கிறது.
ஒவ்வொரு தொழிலாளர் செயல்முறையும் உங்கள் பயன்பாட்டு குறியீட்டை சுயாதீனமாக இயக்கும் ஒரு புதிய Node.js நிகழ்வாகும்.
குறிப்பு:
அடிப்படையில், Cluster தொகுதி புதிய தொழிலாளர்களை உருவாக்க Child Process தொகுதியின் fork() முறையைப் பயன்படுத்துகிறது.
| செயல்முறை வகை | பொறுப்பு |
|---|---|
| மாஸ்டர் |
|
| தொழிலாளர் |
|
அடிப்படை கிளஸ்டரை உருவாக்குதல்
ஒவ்வொரு CPU க்கும் தொழிலாளர் செயல்முறைகளுடன் ஒரு கிளஸ்டரை உருவாக்குவதற்கான ஒரு எளிய எடுத்துக்காட்டு இங்கே:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// This is the master process
console.log(`Master ${process.pid} is running`);
// Fork workers for each CPU core
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
// Listen for worker exits
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died`);
// You can fork a new worker to replace the dead one
console.log('Forking a new worker...');
cluster.fork();
});
} else {
// This is a worker process
// Create an HTTP server
http.createServer((req, res) => {
res.writeHead(200);
res.end(`Hello from Worker ${process.pid}\n`);
// Simulate CPU work
let i = 1e7;
while (i > 0) { i--; }
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
இந்த எடுத்துக்காட்டில்:
தொழிலாளர் தொடர்பு
Child Process தொகுதியில் IPC எவ்வாறு செயல்படுகிறது என்பதைப் போலவே, send() முறை மற்றும் message events ஐப் பயன்படுத்தி மாஸ்டர் மற்றும் தொழிலாளர் செயல்முறைகளுக்கு இடையே தொடர்பு கொள்ளலாம்.
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Track request count for each worker
const requestCounts = {};
// Fork workers
for (let i = 0; i < numCPUs; i++) {
const worker = cluster.fork();
requestCounts[worker.id] = 0;
// Listen for messages from this worker
worker.on('message', (msg) => {
if (msg.cmd === 'incrementRequestCount') {
requestCounts[worker.id]++;
console.log(`Worker ${worker.id} (pid ${worker.process.pid}) has handled ${requestCounts[worker.id]} requests`);
}
});
}
// Every 10 seconds, send the request count to each worker
setInterval(() => {
for (const id in cluster.workers) {
cluster.workers[id].send({
cmd: 'requestCount',
requestCount: requestCounts[id]
});
}
console.log('Total request counts:', requestCounts);
}, 10000);
// Handle worker exit
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died`);
// Fork a new worker to replace it
const newWorker = cluster.fork();
requestCounts[newWorker.id] = 0;
});
} else {
// Worker process
console.log(`Worker ${process.pid} started`);
let localRequestCount = 0;
// Handle messages from the master
process.on('message', (msg) => {
if (msg.cmd === 'requestCount') {
console.log(`Worker ${process.pid} has handled ${msg.requestCount} requests according to master`);
}
});
// Create an HTTP server
http.createServer((req, res) => {
// Notify the master that we handled a request
process.send({ cmd: 'incrementRequestCount' });
// Increment local count
localRequestCount++;
// Send response
res.writeHead(200);
res.end(`Hello from Worker ${process.pid}, I've handled ${localRequestCount} requests locally\n`);
}).listen(8000);
}
பூஜ்ய-கீழேறுதல் மறுதொடக்கம்
கிளஸ்டரிங்கின் முக்கிய நன்மைகளில் ஒன்று கீழேறுதல் இல்லாமல் தொழிலாளர்களை மீண்டும் தொடங்கும் திறனாகும். உங்கள் பயன்பாட்டிற்கான புதுப்பிப்புகளை வெளியிடுவதற்கு இது பயனுள்ளதாக இருக்கும்.
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Store workers
const workers = [];
// Fork initial workers
for (let i = 0; i < numCPUs; i++) {
workers.push(cluster.fork());
}
// Function to restart workers one by one
function restartWorkers() {
console.log('Starting zero-downtime restart...');
let i = 0;
function restartWorker() {
if (i >= workers.length) {
console.log('All workers restarted successfully!');
return;
}
const worker = workers[i++];
console.log(`Restarting worker ${worker.process.pid}...`);
// Create a new worker
const newWorker = cluster.fork();
newWorker.on('listening', () => {
// Once the new worker is listening, kill the old one
worker.disconnect();
// Replace the old worker in our array
workers[workers.indexOf(worker)] = newWorker;
// Continue with the next worker
setTimeout(restartWorker, 1000);
});
}
// Start the recursive process
restartWorker();
}
// Simulate a restart after 20 seconds
setTimeout(restartWorkers, 20000);
// Handle normal worker exit
cluster.on('exit', (worker, code, signal) => {
if (worker.exitedAfterDisconnect !== true) {
console.log(`Worker ${worker.process.pid} died unexpectedly, replacing it...`);
const newWorker = cluster.fork();
workers[workers.indexOf(worker)] = newWorker;
}
});
} else {
// Worker process
// Create an HTTP server
http.createServer((req, res) => {
res.writeHead(200);
res.end(`Worker ${process.pid} responding, uptime: ${process.uptime().toFixed(2)} seconds\n`);
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
இந்த எடுத்துக்காட்டு விளக்குகிறது:
சுமை சமநிலை
Cluster தொகுதி தொழிலாளர் செயல்முறைகளுக்கிடையே உள்வரும் இணைப்புகளை விநியோகிப்பதற்கான உள்ளமைக்கப்பட்ட சுமை சமநிலையைக் கொண்டுள்ளது.
இரண்டு முதன்மை உத்திகள் உள்ளன:
Round-Robin (இயல்புநிலை)
விண்டோஸைத் தவிர அனைத்து தளங்களிலும், Node.js ஒரு சுற்று-ராபின் அணுகுமுறையைப் பயன்படுத்தி இணைப்புகளை விநியோகிக்கிறது, இதில் மாஸ்டர் இணைப்புகளை ஏற்றுக்கொண்டு ஒரு வட்ட வரிசையில் தொழிலாளர்களுக்கு விநியோகிக்கிறது.
குறிப்பு:
விண்டோஸில், போர்ட்களை எவ்வாறு கையாள்கிறது என்பதன் காரணமாக சுமை விநியோகம் வித்தியாசமாக செயல்படுகிறது. விண்டோஸில், தொழிலாளர்கள் இணைப்புகளை ஏற்க போட்டியிடுகிறார்கள்.
முதன்மை தொழிலாளர்
cluster.schedulingPolicy ஐ அமைப்பதன் மூலம் ஒவ்வொரு தொழிலாளரும் இணைப்புகளை நேரடியாக ஏற்றுக்கொள்ள அனுமதிக்கலாம்:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
// Set the scheduling policy to SCHED_NONE (let workers accept connections themselves)
cluster.schedulingPolicy = cluster.SCHED_NONE;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died`);
cluster.fork();
});
} else {
// Worker process
http.createServer((req, res) => {
res.writeHead(200);
res.end(`Hello from Worker ${process.pid}\n`);
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
தொழிலாளர் வாழ்க்கைச் சுழற்சி
உங்கள் கிளஸ்டரை சரியாக நிர்வகிப்பதற்கு தொழிலாளர் வாழ்க்கைச் சுழற்சியைப் புரிந்துகொள்வது முக்கியம்:
| நிகழ்வு | விளக்கம் |
|---|---|
| fork | ஒரு புதிய தொழிலாளர் fork செய்யப்படும் போது வெளியிடப்படுகிறது |
| online | தொழிலாளர் இயங்கும் போது மற்றும் செய்திகளைச் செயலாக்கத் தயாராக இருக்கும் போது வெளியிடப்படுகிறது |
| listening | தொழிலாளர் இணைப்புகளுக்குக் கேட்கத் தொடங்கும் போது வெளியிடப்படுகிறது |
| disconnect | ஒரு தொழிலாளரின் IPC சேனல் துண்டிக்கப்படும் போது வெளியிடப்படுகிறது |
| exit | ஒரு தொழிலாளர் செயல்முறை வெளியேறும் போது வெளியிடப்படுகிறது |
const cluster = require('cluster');
const http = require('http');
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork a worker
const worker = cluster.fork();
// Listen for all worker lifecycle events
worker.on('fork', () => {
console.log(`Worker ${worker.process.pid} is being forked`);
});
worker.on('online', () => {
console.log(`Worker ${worker.process.pid} is online`);
});
worker.on('listening', (address) => {
console.log(`Worker ${worker.process.pid} is listening on port ${address.port}`);
});
worker.on('disconnect', () => {
console.log(`Worker ${worker.process.pid} has disconnected`);
});
worker.on('exit', (code, signal) => {
console.log(`Worker ${worker.process.pid} exited with code ${code} and signal ${signal}`);
if (signal) {
console.log(`Worker was killed by signal: ${signal}`);
} else if (code !== 0) {
console.log(`Worker exited with error code: ${code}`);
} else {
console.log('Worker exited successfully');
}
});
// After 10 seconds, gracefully disconnect the worker
setTimeout(() => {
console.log('Gracefully disconnecting worker...');
worker.disconnect();
}, 10000);
} else {
// Worker process
console.log(`Worker ${process.pid} started`);
// Create an HTTP server
http.createServer((req, res) => {
res.writeHead(200);
res.end(`Hello from Worker ${process.pid}\n`);
}).listen(8000);
// If worker is disconnected, close the server
process.on('disconnect', () => {
console.log(`Worker ${process.pid} disconnected, closing server...`);
// In a real application, you'd want to close all connections and clean up resources
process.exit(0);
});
}
நேர்த்தியான அணைப்பு
உங்கள் தொழிலாளர் செயல்முறைகள் வெளியேறும் முன் இருக்கும் கோரிக்கைகளை முடிக்க அனுமதிக்க ஒரு நேர்த்தியான அணைப்பு முக்கியமானது.
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
// Handle termination signals
process.on('SIGTERM', () => {
console.log('Master received SIGTERM, initiating graceful shutdown...');
// Notify all workers to finish their work and exit
Object.values(cluster.workers).forEach(worker => {
console.log(`Sending SIGTERM to worker ${worker.process.pid}`);
worker.send('shutdown');
});
// Set a timeout to force-kill workers if they don't exit gracefully
setTimeout(() => {
console.log('Some workers did not exit gracefully, forcing shutdown...');
Object.values(cluster.workers).forEach(worker => {
if (!worker.isDead()) {
console.log(`Killing worker ${worker.process.pid}`);
worker.process.kill('SIGKILL');
}
});
// Exit the master
console.log('All workers terminated, exiting master...');
process.exit(0);
}, 5000);
});
// Handle worker exits
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} exited (${signal || code})`);
// If all workers have exited, exit the master
if (Object.keys(cluster.workers).length === 0) {
console.log('All workers have exited, shutting down master...');
process.exit(0);
}
});
// Log to show the master is ready
console.log(`Master ${process.pid} is ready with ${Object.keys(cluster.workers).length} workers`);
console.log('Send SIGTERM to the master process to initiate graceful shutdown');
} else {
// Worker process
console.log(`Worker ${process.pid} started`);
// Track if we're shutting down
let isShuttingDown = false;
let activeConnections = 0;
// Create HTTP server
const server = http.createServer((req, res) => {
// Track active connection
activeConnections++;
// Simulate a slow response
setTimeout(() => {
res.writeHead(200);
res.end(`Hello from Worker ${process.pid}\n`);
// Connection complete
activeConnections--;
// If we're shutting down and no active connections, close the server
if (isShuttingDown && activeConnections === 0) {
console.log(`Worker ${process.pid} has no active connections, closing server...`);
server.close(() => {
console.log(`Worker ${process.pid} closed server, exiting...`);
process.exit(0);
});
}
}, 2000);
});
// Start server
server.listen(8000);
// Handle shutdown message from master
process.on('message', (msg) => {
if (msg === 'shutdown') {
console.log(`Worker ${process.pid} received shutdown message, stopping new connections...`);
// Set shutdown flag
isShuttingDown = true;
// Stop accepting new connections
server.close(() => {
console.log(`Worker ${process.pid} closed server`);
// If no active connections, exit immediately
if (activeConnections === 0) {
console.log(`Worker ${process.pid} has no active connections, exiting...`);
process.exit(0);
} else {
console.log(`Worker ${process.pid} waiting for ${activeConnections} connections to finish...`);
}
});
}
});
// Also handle direct termination signal
process.on('SIGTERM', () => {
console.log(`Worker ${process.pid} received SIGTERM directly`);
// Use the same shutdown logic
isShuttingDown = true;
server.close(() => process.exit(0));
});
}
சிறந்த நடைமுறைகள்
எச்சரிக்கை:
பல தொழிலாளர்களைப் பயன்படுத்தும் போது கோப்பு-அடிப்படையிலான பூட்டு மற்றும் பிற பகிரப்பட்ட வளங்களுடன் கவனமாக இருங்கள். ஒற்றை-செயல்முறை பயன்பாட்டில் பாதுகாப்பான செயல்பாடுகள் பல தொழிலாளர்களுடன் போட்டி நிலைமைகளை ஏற்படுத்தக்கூடும்.
Cluster தொகுதிக்கான மாற்றுகள்
Cluster தொகுதி சக்திவாய்ந்ததாக இருந்தாலும், பல கோர்களில் Node.js பயன்பாடுகளை இயக்குவதற்கு மாற்றுகள் உள்ளன:
| அணுகுமுறை | விளக்கம் | பயன்பாட்டு வழக்கு |
|---|---|---|
| PM2 | உள்ளமைக்கப்பட்ட சுமை சமநிலை மற்றும் கிளஸ்டரிங்குடன் Node.js பயன்பாடுகளுக்கான ஒரு செயல்முறை மேலாளர் | வலுவான செயல்முறை மேலாண்மை தேவைப்படும் உற்பத்தி பயன்பாடுகள் |
| சுமை சமநிலை | Nginx போன்ற சுமை சமநிலையின் பின்னால் பல Node.js நிகழ்வுகளை இயக்குதல் | பல சேவையகங்கள் அல்லது கொள்கலன்களில் சுமையை விநியோகித்தல் |
| தொழிலாளர் நூல்கள் | CPU-தீவிர பணிகளுக்கான இலகுவான நூலிடல் (Node.js >= 10.5.0) | ஒற்றை செயல்முறைக்குள் CPU-தீவிர செயல்பாடுகள் |
| கொள்கலன்கள் | பல கொள்கலனாக்கப்பட்ட நிகழ்வுகளை இயக்குதல் (Docker மற்றும் Kubernetes உடன்) | நவீன கிளவுட் சூழல்களில் அளவிடக்கூடிய, விநியோகிக்கப்பட்ட பயன்பாடுகள் |
மேம்பட்ட சுமை சமநிலை உத்திகள்
Cluster தொகுதியின் இயல்புநிலை சுற்று-ராபின் சுமை சமநிலை பல பயன்பாடுகளுக்கு நன்றாக வேலை செய்யும் போது, குறிப்பிட்ட பயன்பாட்டு வழக்குகளுக்கு மேம்பட்ட உத்திகள் தேவைப்படலாம்.
1. எடை சுற்று-ராபின்
const cluster = require('cluster');
const http = require('http');
const os = require('os');
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Create workers with different weights
const workerWeights = [3, 2, 1]; // First worker gets 3x more load than the last
const workers = [];
// Create workers based on weights
workerWeights.forEach((weight, index) => {
for (let i = 0; i < weight; i++) {
const worker = cluster.fork({ WORKER_WEIGHT: weight });
worker.weight = weight;
workers.push(worker);
}
});
// Track the next worker to use
let workerIndex = 0;
// Create a load balancer server
http.createServer((req, res) => {
// Simple round-robin with weights
const worker = workers[workerIndex++ % workers.length];
worker.send('handle-request', req.socket);
}).listen(8000);
} else { // Worker code
process.on('message', (message, socket) => {
if (message === 'handle-request' && socket) {
// Handle the request
socket.end(`Handled by worker ${process.pid}\n`);
}
});
}
2.குறைந்த இணைப்புகள்
const cluster = require('cluster');
const http = require('http');
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Create workers and track their connection counts
const workers = [];
const numCPUs = require('os').cpus().length;
for (let i = 0; i < numCPUs; i++) {
const worker = cluster.fork();
worker.connectionCount = 0;
workers.push(worker);
// Track worker connections
worker.on('message', (msg) => { if (msg.type === 'connection') { worker.connectionCount = msg.count; } });
}
// Create load balancer
http.createServer((req, res) => {
// Find worker with least connections
let minConnections = Infinity;
let selectedWorker = null;
for (const worker of workers) {
if (worker.connectionCount < minConnections) {
minConnections = worker.connectionCount;
selectedWorker = worker;
}
}
if (selectedWorker) {
selectedWorker.send('handle-request', req.socket);
}
}).listen(8000);
}
செயல்திறன் கண்காணிப்பு மற்றும் அளவீடுகள்
ஆரோக்கியமான பயன்பாட்டை பராமரிப்பதற்கு உங்கள் கிளஸ்டரின் செயல்திறனைக் கண்காணிப்பது முக்கியமானது. அடிப்படை அளவீடுகள் சேகரிப்பைச் செயல்படுத்துவது எப்படி என்பது இங்கே:
const cluster = require('cluster');
const os = require('os');
const promClient = require('prom-client');
if (cluster.isMaster) {
// Create metrics registry
const register = new promClient.Registry();
promClient.collectDefaultMetrics({ register });
// Custom metrics
const workerRequests = new promClient.Counter({
name: 'worker_requests_total',
help: 'Total requests handled by worker',
labelNames: ['worker_pid']
});
register.registerMetric(workerRequests);
// Fork workers
for (let i = 0; i < os.cpus().length; i++) {
const worker = cluster.fork();
worker.on('message', (msg) => {
if (msg.type === 'request_processed') {
workerRequests.inc({ worker_pid: worker.process.pid });
}
});
}
// Expose metrics endpoint
require('http').createServer(async (req, res) => {
if (req.url === '/metrics') {
res.setHeader('Content-Type', register.contentType);
res.end(await register.metrics());
}
}).listen(9090);
} else {
// Worker code
let requestCount = 0;
require('http').createServer((req, res) => {
requestCount++;
process.send({ type: 'request_processed' });
res.end(`Request ${requestCount} handled by worker ${process.pid}\n`);
}).listen(8000);
}
கண்காணிக்க வேண்டிய முக்கிய அளவீடுகள்
கொள்கலன் ஒருங்கிணைப்பு
Docker மற்றும் Kubernetes போன்ற கொள்கலனாக்கப்பட்ட சூழல்களில் இயக்கும் போது, இந்த சிறந்த நடைமுறைகளைக் கவனியுங்கள்:
1. செயல்முறை மேலாண்மை
// Dockerfile example for a Node.js cluster app
FROM node:16-slim
WORKDIR /app
COPY package*.json ./
RUN npm install --production
# Copy application code
COPY . .
# Use the node process as PID 1 for proper signal handling
CMD ["node", "cluster.js"]
# Health check
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/health || exit 1
2. Kubernetes Deployment
# k8s-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: node-cluster-app
spec:
replicas: 3 # Number of pods
selector:
matchLabels:
app: node-cluster
template:
metadata:
labels:
app: node-cluster
spec:
containers:
- name: node-app
image: your-image:latest
ports:
- containerPort: 8000
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1Gi"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
பொதுவான பொறிகுழிகள் மற்றும் தீர்வுகள்
1. தொழிலாளர்களில் நினைவக கசிவுகள்
சிக்கல்: தொழிலாளர் செயல்முறைகளில் நினைவக கசிவுகள் படிப்படியான நினைவக வளர்ச்சியை ஏற்படுத்தும்.
தீர்வு: நினைவக பயன்பாட்டின் அடிப்படையில் தொழிலாளர் மறுசுழற்சியை செயல்படுத்தவும்.
// In worker process
const MAX_MEMORY_MB = 500; // Max memory in MB before recycling
function checkMemory() {
const memoryUsage = process.memoryUsage();
const memoryMB = memoryUsage.heapUsed / 1024 / 1024;
if (memoryMB > MAX_MEMORY_MB) {
console.log(`Worker ${process.pid} memory ${memoryMB.toFixed(2)}MB exceeds limit, exiting...`);
process.exit(1); // Let cluster restart the worker
}
}
// Check memory every 30 seconds
setInterval(checkMemory, 30000);
2. Thunder Herd சிக்கல்
சிக்கல்: மறுதொடக்கத்திற்குப் பிறகு அனைத்து தொழிலாளர்களும் ஒரே நேரத்தில் இணைப்புகளை ஏற்றுக்கொள்கிறார்கள்.
தீர்வு: staggered startup ஐ செயல்படுத்தவும்.
// In master process
if (cluster.isMaster) {
const numWorkers = require('os').cpus().length;
function forkWorker(delay) {
setTimeout(() => {
const worker = cluster.fork();
console.log(`Worker ${worker.process.pid} started after ${delay}ms delay`);
}, delay);
}
// Stagger worker starts by 1 second
for (let i = 0; i < numWorkers; i++) {
forkWorker(i * 1000);
}
}
3. தொழிலாளர் பட்டினி
சிக்கல்: சில தொழிலாளர்கள் மற்றவர்களை விட அதிக சுமையைப் பெறுகிறார்கள்.
தீர்வு: சரியான சுமை சமநிலை மற்றும் கண்காணிப்பை செயல்படுத்தவும்.
// Track request distribution
const requestDistribution = new Map();
// In master process
if (cluster.isMaster) {
// ...
// Monitor request distribution
setInterval(() => {
console.log('Request distribution:');
requestDistribution.forEach((count, pid) => {
console.log(` Worker ${pid}: ${count} requests`);
});
}, 60000);
// Track requests per worker
cluster.on('message', (worker, message) => {
if (message.type === 'request_handled') {
const count = requestDistribution.get(worker.process.pid) || 0;
requestDistribution.set(worker.process.pid, count + 1);
}
});
}
சுருக்கம்
Node.js Cluster தொகுதி பல CPU கோர்களில் உங்கள் பயன்பாட்டை அளவிட ஒரு திறமையான வழியை வழங்குகிறது:
கிளஸ்டரிங்கைப் புரிந்துகொண்டு சரியாகச் செயல்படுத்துவதன் மூலம், கிடைக்கக்கூடிய அனைத்து CPU வளங்களையும் திறம்படப் பயன்படுத்தும் உயர்-செயல்திறன், நம்பகமான Node.js பயன்பாடுகளை உருவாக்க முடியும்.
பயிற்சி
சரியான தொகுதி பெயரை தேர்வு செய்யவும்.
The ______ module allows you to create child processes that run simultaneously and share the same server port.